home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_12_12 / colvin / unwind.h < prev   
Encoding:
C/C++ Source or Header  |  1994-10-05  |  2.2 KB  |  68 lines

  1. ////////////////////////////////////////////////////////////
  2. // UNWIND.H
  3. // Copyright 1994 Gregory Colvin.
  4. // May be distributed free with this notice.
  5. #include <stdlib.h>
  6. #include <setjmp.h>
  7.  
  8. // These macros emulate the corresponding C++ keywords.
  9. #define try                              \
  10.    int eh_err=0;                         \
  11.    {  Handler Handler;                   \
  12.       eh_err = setjmp(Handler.buf);      \
  13.       if (!eh_err)
  14. #define catch(dcl)                       \
  15.    }                                     \
  16.    dcl = eh_err;                         \
  17.    if (eh_err)
  18. #define throw(err) Handler::Throw(err)
  19.  
  20. // Entry on stack of exception handlers.
  21. struct Handler {
  22.    friend struct Pusher;
  23.    friend struct Unwindable;
  24.    Handler() : prev(handler), link(0) { handler = this; }
  25.    ~Handler() { handler = handler->prev; }
  26.    static void Throw(int);          // throw an exception
  27.    jmp_buf buf;                     // for use by try macro
  28. private:
  29.    Handler* prev;                   // stack of handlers
  30.    Unwindable* link;                // stack of catchables
  31.    static Handler* handler;         // current handler
  32.    static void push(Unwindable*,size_t);
  33. };
  34.  
  35. // Pusher is used by the UNWINDABLE macro to make objects 
  36. // catchable when their constructor is finished.
  37. struct Pusher {
  38.    friend struct Unwindable;
  39.    Pusher(Unwindable* p,size_t s) : pushed(p), size(s) {}
  40.    ~Pusher() { Handler::push(pushed,size); }
  41. private:
  42.    Unwindable* pushed;
  43.    size_t size;
  44. };
  45. #define UNWINDABLE Pusher pusher(this,sizeof *this)
  46.  
  47. // Unwindables can be destroyed when an exception is thrown.
  48. struct Unwindable {
  49.    friend Handler;
  50.    Unwindable() { UNWINDABLE; count++; }
  51.    Unwindable(const Unwindable&) { UNWINDABLE; count++; }
  52.    Unwindable& operator=(const Unwindable&) { 
  53.       UNWINDABLE; 
  54.       return *this;
  55.    }
  56.    virtual ~Unwindable() { --count; }
  57.    void* operator new(size_t);
  58.    void operator delete(void* p) { ::operator delete(p); }
  59.    static unsigned Count() { return count; }
  60. private:
  61.    Unwindable* link;       // next object on stack
  62.    size_t size;            // size of complete object
  63.    static unsigned count;  // number of objects
  64.    int within(Unwindable*);
  65. };
  66.  
  67.  
  68.